require 'iconv'
class IncidentesController < ApplicationController
  #MODULE: Evaluaciones
  before_filter :find_usuario
  before_filter :datos_premiacion,:only=>[:premiar,:premio]  
  # GET /incidentes
  # GET /incidentes.xml
  def controller_name
    @controller_name= "Hechos Significativos"
  end
  
  def index
  end

  # GET /incidentes/1
  # GET /incidentes/1.xml 
  def show
    @incidente = Incidente.find(params[:id])
    #@tiene_perfil_atencion = current_user.tiene_perfil?(Parametro.find_by_codigo("PPERF01").try(:nombre))
    #@es_quien_registro = (current_user.id==@incidente.registrador_id)
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @incidente }
    end
  end

  # GET /incidentes/new
  # GET /incidentes/new.xml
  #TODO: cambiar @show_all por metodo en Usuario
  def new
    @incidente = Incidente.new
    @incidente.fecha = Date.today
    @show_all = current_user.tiene_perfil?(Parametro.find_by_codigo("PPERF01").parametrizable.try(:nombre))
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @incidente }
    end
  end

  # GET /incidentes/1/edit
  def edit
    @incidente = Incidente.find(params[:id])
    @afectado = @incidente.funcionario
    @show_all = current_user.tiene_perfil?(Parametro.find_by_codigo("PPERF01").parametrizable.try(:nombre))
  end

  # POST /incidentes
  # POST /incidentes.xml
  def create
    @incidente = Incidente.new(params[:incidente])
    @incidente.registrador_id = current_user.id
    @show_all = current_user.tiene_perfil?(Parametro.find_by_codigo("PPERF01").parametrizable.try(:nombre))
    respond_to do |format|
      if @incidente.save
        begin
          IncidenteMailer.deliver_creation_notification(@incidente,:parametro=>"PPERF01",:direcciones=>@incidente.destinatarios_email)
        rescue
        end
        flash[:notice] =  'Hecho Significativo creado correctamente.'
        format.html { params[:oper].nil? ? redirect_to(@incidente) : render(:text => "Ok")}
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @incidente.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /incidentes/1
  # PUT /incidentes/1.xml
  def update
    @incidente = Incidente.find(params[:id])
    params[:incidente][:premiacion_attributes][:incidente_id]=params[:id] if params[:incidente][:premiacion_attributes]
    #params[:incidente][:premiacion_attributes][:funcionario_id]=@incidente.funcionario_id if params[:incidente][:premiacion_attributes]
    #@show_all = current_user.subordinados.count > 1
    @show_all = current_user.tiene_perfil?(Parametro.find_by_codigo("PPERF01").parametrizable.try(:nombre))
    respond_to do |format|
      if @incidente.update_attributes(params[:incidente])
        flash[:notice] = 'Hecho Significativo correctamente.'
        format.html { redirect_to(@incidente) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @incidente.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /incidentes/1
  # DELETE /incidentes/1.xml
  def destroy
    @incidente = Incidente.find(params[:id])
    @incidente.destroy

    respond_to do |format|
      format.html { redirect_to(incidentes_url) }
      format.xml  { head :ok }
    end
  end

  def select_usuarios
    #Realizar consulta
    if params[:page]
      params["_search"]="true" if params[:activo]
      registros, count = find_by_params(params, :class => Usuario.vigentes)
      # Construct a hash from the ActiveRecord result
      return_data = Hash.new()
      return_data[:page] = params[:page]
      return_data[:total] = (count.to_f / params[:rows].to_i).ceil
      return_data[:records] = count

      return_data[:rows] = registros.collect{|u| {:id => u.id,
          :cell => [
            u.nombres, u.apellidos
          ]}}

      render :text => return_data.to_json, :layout => false    
    end
  end
  
  def datos #IGNORE
    #Si es administrador ignorar las reglas
    scope,conds = [:por_usuario_id,@usuario.id]
    scope,conds = [:por_cargos_subordinados_id,[@usuario.cargo.todos_subordinados,@usuario.sucursal_id]] if (params["tipo_lista"] && params["tipo_lista"]=="1" && @usuario.cargo)
    params.delete("tipo_lista")
    params.delete("usuario_id")
    #Parametros
    registros, count = find_by_params(params, :class => Incidente.send(scope,conds),:includes=>[:funcionario])

    # Construct a hash from the ActiveRecord result
    return_data = Hash.new()
    return_data[:page] = params[:page]
    return_data[:total] = (count.to_f / params[:rows].to_i).ceil
    return_data[:records] = count

    return_data[:rows] = registros.collect{|u| {:id=>u.id,
        :cell=>[
          u.fecha,u.registrador.try(:nombre),u.funcionario.try(:nombre),u.identificador.try(:nombre),u.descripcion,u.hecho.try(:nombre)
        ]}}

    # Convert the hash to a json object
    render :text=>return_data.to_json, :layout=>false
  end

  #TODO: crear el metodo 'superior' en usuario
  def cambiar_cargo #IGNORE
    if params[:funcionario_id] && !params[:funcionario_id].empty?
      @afectado=Usuario.find(params[:funcionario_id])
      render :update do |page|
        page.replace_html :cargo_y_superior, :partial =>'cargo_y_superior'
        page.replace :popup_factor, :partial =>'popup_factor'
        page<< "$('#colorbox_factor_reconocimiento_1').colorbox()"
      end
    else
      render :nothing => true
    end
  end


  def reporte_individual #DESC: Visualizar el reporte de incidente críticos por usuario.
    if PremiacionEscala.first
      @datos=[]
      if request.method == :post and params[:format].nil?
        reporte_individual_datos=Incidente.reporte_individual(params)
        @funcionario=reporte_individual_datos[:funcionario]
        @datos=reporte_individual_datos[:datos] || []
        @resumen =reporte_individual_datos[:resumen]
      end

      respond_to do |wants|
        wants.html
        wants.csv do
          funcionario=Usuario.find(params[:funcionario_id])
          inicio=params[:inicio].to_date
          fin=params[:fin].to_date
          datos= funcionario.incidentes.por_periodo(inicio,fin)
      
          tsv_string = FasterCSV.generate(:col_sep => "\t") do |tsv|
            tsv << ["Fecha","Mes","Supervisor","Quien Identifico","Funcionario",
              "Cargo","Area","Filial","Descripcion Del Hecho","Hecho",
              "Apercibimiento","Dias de Suspencion","Articulo","Obs. RRHH"]
          
            datos.each do |i|
              tsv << [Date.today,
                I18n.l(i.fecha,:format=>:full_month_name),
                funcionario.superiores.first.try(:nombre),
                i.identificador.nombre,
                funcionario.nombre,
                funcionario.cargo.try(:nombre),
                funcionario.cargo.try(:area).try(:nombre),
                funcionario.sucursal.try(:nombre),
                i.descripcion,
                i.hecho.nombre,
                i.apercibimiento,
                i.suspencion_dias,
                i.articulo,
                i.observacion]
            end
          end
          content = Iconv.conv("utf-16le", "utf-8", tsv_string)
          send_data content,
            :disposition => "attachment; filename=Reporte_Individual_Incidentes_"+@funcionario.id.to_s+".csv"
        end
      end
    else
      redirect_to usuario_evaluados_path(@usuario)
    end
  end

  def descargar_reporte #DESC: Descargar el reporte de incidentes críticos
    #Si es administrador ignorar las reglas
    current_user.tiene_perfil?("Administrador") ? funcionarios=Usuario.activos : funcionarios=current_user.usuarios_para_reporte

    filename="Reporte_Hechos_Significativos_#{Date.today.to_s}.csv"
    tsv_string = FasterCSV.generate(:col_sep => ",") do |tsv|
      tsv << ["Fecha","Mes","Supervisor","Quien Identifico","Funcionario",
        "Cargo","Area","Filial","Descripcion Del Hecho","Hecho",
        "Apercibimiento","Dias de Suspencion","Articulo","Obs. RRHH"]
      funcionarios.each do |funcionario|
        datos= funcionario.incidentes

        datos.each do |i|
          tsv << [Date.today,
            I18n.localize(i.fecha,:format=>:full_month_name),
            funcionario.superiores.first.try(:nombre),
            i.identificador.nombre,
            funcionario.nombre,
            funcionario.cargo.try(:nombre),
            funcionario.cargo.try(:area).try(:nombre),
            funcionario.sucursal.try(:nombre),
            i.descripcion,
            i.hecho_nombre,
            i.apercibimiento?,
            i.suspecion_dias,
            i.articulo,
            i.observacion]
        end
      end
    end
    content =Iconv.conv("utf-16le", "utf-8", tsv_string)
    send_data content,
      :disposition => "attachment; filename=#{filename}"
  end

  def  premiar
  end
  def premio
    render :template=>'incidentes/premiar'
  end

  def ranking
    @datos=[]
    usuarios=Usuario.activos
    if request.method==:post
      hechos_significativos=Incidente.por_periodo(Date.strptime(params[:ranking][:inicio], "%d/%m/%Y"),Date.strptime(params[:ranking][:fin], "%d/%m/%Y")).group_by(&:funcionario_id)
      #redirect_to ranking_usuario_incidentes_path(@usuario)
    else
      hechos_significativos=Incidente.all.group_by(&:funcionario_id)
    end
    usuarios.each do |u|
      next unless hechos_significativos[u.id]
      i=hechos_significativos[u.id].first.clone
      i.puntuacion_registrada=hechos_significativos[u.id].sum(&:puntuacion)
      @datos<<i
    end
    @datos=@datos.sort_by(&:puntuacion_registrada).reverse
    
  end


  def reconocimientos
    @datos=[]
    if request.method==:post
      hechos_significativos=Incidente.por_periodo(Date.strptime(params[:reconocimientos][:inicio], "%d/%m/%Y"),Date.strptime(params[:reconocimientos][:fin], "%d/%m/%Y"))
      hechos_significativos=hechos_significativos.group_by(&:reconocimiento_index)
      hechos_significativos.each do |key,hs|
        @datos<<hs.sort_by(&:puntuacion_acumulada).last
      end
    end

  end


  private
  def find_usuario
    @usuario = Usuario.find params[:usuario_id] || current_user
  end

  def datos_premiacion
    @incidente=Incidente.find(params[:id])
    @incidentes=(@incidente.premiacion.try(:incidentes) || @incidente.hechos_habilitados)
    @premiacion=@incidente.premiacion || Premiacion.new(
      :funcionario_id=>@incidente.funcionario_id,
      :incidente_id=>@incidente.id,
      :fecha=>Date.today,
      :nivel_nombre=>@incidente.nivel_nombre,
      :nivel_escala=>@incidente.nivel_escala

    )
    @incidente.premiacion||=@premiacion
  end
end
